// http://www.axios-js.com/docs/#axios-create-config
import { notification } from 'antd' ;
import axios from 'axios'
import {NOT_LOGIN_ERROR, REFRESH_TOKEN_ERROR, refreshTokenKey, SUCCESS, tokenKey} from "@/utils/constants";
import {
    getRefreshToken,
    getToken,
    removeRrefeshToken,
    removeToken,
    setRefreshToken,
    setToken
} from "@/utils/tokenCookies";
import confirm from "antd/lib/modal/confirm";
import queryString from "query-string";
import {replace} from "lodash";




// 是否正在刷新的标记
let isRefreshing = false

// 重试队列，每一项将是一个待执行的函数形式
let requests:any[] = []

//防止重复请求弹框
let redirect=false;
 export const axiosInstance = axios.create({
    withCredentials:true,
    timeout: 20 * 1000, // 20s
    baseURL: import.meta.env.VITE_REACT_APP_SERVICE_BASE_API,
})
// http request 拦截器
axiosInstance.interceptors.request.use(
    (req: any) => {
        //设置token
        if(getToken()){
            req.headers[tokenKey]=getToken();
        }
        // 可以进行一些请求参数解析
        return req
    },
    (error) => Promise.reject(error),
)

axiosInstance.interceptors.response.use(
    (res: any) => {
        console.log('res', res)
        if (res.data.code==SUCCESS) {
            // 如果是文件流，直接过
            if (res.config.responseType === 'blob') {
                return res
            }
            //某些情况下后端没有返回数据 返回空对象
            if(res.data.data){
                return res.data.data;
            }
            return {};
        }else if(res.data.code===REFRESH_TOKEN_ERROR) {
            //无感刷新token 这个功能暂时不做 后端暂时不返回这个状态代码
            const config = res.config
            console.log('config', config)
            if (!isRefreshing) {
                isRefreshing = true;
                axiosInstance({
                    url: '/base/refreshToken',
                    method: 'get',
                    headers: {
                        [refreshTokenKey]: getRefreshToken(),
                        [tokenKey]:getToken()
                    }
                }).then(r => {
                    if (r.data.token) {
                        setToken(r.data.token)
                    }
                    if (r.data.refreshToken) {
                        setRefreshToken(r.data.refreshToken);
                    }
                    console.log("重试请求配置" + config.toString())
                    config.baseURL = '' // url已经带上了/api，避免出现/api/api的情况

                    // 已经刷新了token，将所有队列中的请求进行重试
                    requests.forEach(cb => cb())
                    return axiosInstance(config)
                }).catch(res => {
                    return Promise.reject(new Error(res.message || 'Error'));
                }).finally(() => {
                    isRefreshing = false;
                })
            } else {
                // 正在刷新token，返回一个未执行resolve的promise
                return new Promise((resolve) => {
                    // 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
                    requests.push(() => {
                        config.baseURL = ''
                        config.headers[tokenKey] = ""
                        resolve(axiosInstance(config))
                    })
                })

            }
        }else if(res.data.code==NOT_LOGIN_ERROR){
            if(!redirect){
                redirect=true;
                confirm({
                    title: '认证失败',
                    content: '认证失败，请点击确定重新登录！！！',
                    okText: '确定',
                    okType: 'danger',
                    onOk() {
                        removeToken();
                        removeRrefeshToken();
                        const { origin, hash } = window.location;
                        console.log('window.location', window.location)
                        let searchParams=queryString.stringify({redirect: replace(hash,'')})
                        let newURL=origin+"/#/login?"+searchParams;
                        window.location.replace(newURL);
                        redirect=false;
                    },
                });
            }

        }
        else{
            //业务失败
            notification.error({
                message: `业务失败：${res.data?.msg}`,
                duration: 3,
            });
            //返回失败
            return Promise.reject(res)
        }

    },
    // 请求失败
    (error : any) => {
        console.log('error', error)
        let errText = '很抱歉，出错了~！'
        if (error instanceof Error) errText = error.toString()
        if (error.response.status == 401) {
            notification.error({
                message: '登录状态失效，请重新登录！',
                duration: 2,
                onClose: () => {
                    window.location.href = `${error.response.headers.location}`
                },
            })
        } else if (errText.indexOf('timeout') > -1) {
            notification.error({
                message: '请求超时，请刷新页面重新发起请求。',
                duration: 5,
            })

        } else {
            notification.error({
                message: errText,
            })
        }
        return Promise.reject(false)
    }
)
